package com.liuyi.netty.im.lychat.modular.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liuyi.netty.im.commons.codes.CodeConst;
import com.liuyi.netty.im.lychat.config.base.BaseQueryController;
import com.liuyi.netty.im.lychat.modular.controller.model.GroupMemberModel.Add;
import com.liuyi.netty.im.lychat.modular.entity.GroupMember;
import com.liuyi.netty.im.lychat.modular.enums.GroupRole;
import com.liuyi.netty.im.lychat.modular.service.IChatSessionService;
import com.liuyi.netty.im.lychat.modular.service.IGroupMemberService;
import com.liuyi.netty.im.lychat.modular.service.IGroupService;
import com.liuyi.netty.im.server.util.ImHelp;
import com.liuyi.netty.im.server.util.ImUtil;
import com.liuyi.rapid.develop.tool.resp.RespCall;
import com.liuyi.rapid.develop.tool.resp.Response;
import com.liuyi.rapid.develop.tool.resp.ResponseCall;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.Length;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

import static org.springframework.http.ResponseEntity.ok;

/**
 * <p>
 * 群组成员表 前端控制器
 * </p>
 *
 * @author mybatis-plus
 * @since 2021-12-29
 */
@Api(value = "", tags = {"群组成员表"})
@RestController
@RequestMapping("/modular/group-member")
public class GroupMemberController implements BaseQueryController<GroupMember, IGroupMemberService> {

    @Resource
    private IGroupMemberService groupMemberService;
    @Resource
    private IChatSessionService chatSessionService;
    @Resource
    private IGroupService groupService;

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "groupId", value = "群id")
    })
    @ApiOperation(value = "解散群", notes = "", httpMethod = "POST")
    @PostMapping("/dissolveGroup/{groupId}")
    public ResponseEntity<Response<String>> dissolveGroup(@PathVariable String groupId) {
        String userId = StpUtil.getLoginIdAsString();
        groupService.dissolveGroup(userId, groupId);
        return ok(ResponseCall.success("群聊解散成功", ImHelp.sessionId(CodeConst.SessionType.GROUP, groupId)).okShow());
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "groupId", value = "群聊id")
    })
    @ApiOperation(value = "退出群聊", notes = "", httpMethod = "POST")
    @PostMapping("/quitGroup/{groupId}")
    @Transactional(rollbackFor = {Exception.class})
    public ResponseEntity<Response<String>> quitGroup(@PathVariable String groupId) {
        String userId = StpUtil.getLoginIdAsString();
        GroupMember groupMember = server().cache().getByUserIdAndGroupId(userId, groupId);
        if (groupMember == null) {
            return RespCall.error("您已退出该群聊");
        }
        if (groupMember.getGroupRole().equals(GroupRole.MANAGE)) {
            return RespCall.error("抱歉，您是群主，不可执行该操作，您可以尝试解散群聊。");
        }
        if (!server().remove(q().eq(GroupMember.USER_ID, StpUtil.getLoginIdAsString()).eq(GroupMember.GROUP_NO, groupId).ne(GroupMember.GROUP_ROLE, GroupRole.MANAGE))) {
            return RespCall.error("退出失败，请刷新后重试");
        }
        String sessionId = ImHelp.sessionId(CodeConst.SessionType.GROUP, groupId);
        chatSessionService.removeSession(userId, sessionId);
        server().cache().removeGetByUserIdAndGroupId(userId, groupId);
        server().cache().removeListByGroupId(groupId);
        server().cache().removeListManageByGroupId(groupId);
        ImUtil.quitGroupMessage(groupId, groupMember.getGroupNick() + "退出该群聊");
        return ok(ResponseCall.success("退出成功", sessionId).okShow());
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "groupName", value = "群组名")
    })
    @ApiOperation(value = "创建群聊", notes = "", httpMethod = "POST")
    @PostMapping("/createGroup/{groupName}")
    public ResponseEntity<Response<String>> createGroup(@PathVariable @Length(max = 12, message = "群聊名称最长12个字符") String groupName) {
        String groupId = groupService.createGroup(groupName, StpUtil.getLoginIdAsString());
        return ok(ResponseCall.success("创建成功", ImHelp.sessionId(CodeConst.SessionType.GROUP, groupId)).okShow());
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "groupId", value = "群组id"),
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "nick", value = "昵称")
    })
    @ApiOperation(value = "修改昵称", notes = "", httpMethod = "POST")
    @PostMapping("/modifyNick/{groupId}/nick/{nick}")
    public ResponseEntity<Response<Void>> modifyNick(@PathVariable String groupId,
                                                     @PathVariable @Length(max = 12, message = "群昵称最长12个字符") String nick) {
        String userId = StpUtil.getLoginIdAsString();
        if (server().cache().countByUserIdAndGroupId(userId, groupId) == 0) {
            return RespCall.error("抱歉，您不是该群组成员");
        }
        server().update(new GroupMember().setGroupNick(nick), q().eq(GroupMember.GROUP_NO, groupId).eq(GroupMember.USER_ID, userId));
        server().cache().removeGetByUserIdAndGroupId(userId, groupId);
        return ok(ResponseCall.<Void>successMsg("修改成功").okShow());
    }

    @ApiOperation(value = "邀请入群", notes = "", httpMethod = "POST")
    @PostMapping("/add")
    public ResponseEntity<Response<Void>> add(@Valid @RequestBody Add p) {
        if (server().cache().countByUserIdAndGroupId(StpUtil.getLoginIdAsString(), p.getGroupId()) == 0) {
            return RespCall.error("抱歉，您不是该群组成员，不可邀请好友入群");
        }
        server().addMember(p.getGroupId(), p.getUserIds());
        return ok(ResponseCall.<Void>successMsg("邀请成功").okShow());
    }

    @Override
    public IGroupMemberService server() {
        return groupMemberService;
    }

    @Override
    public void pre(QueryWrapper<GroupMember> wrapper, String method) {
        wrapper.eq(GroupMember.USER_ID, StpUtil.getLoginIdAsString());
    }

    @Override
    public void wrapper(GroupMember data) {
        server().wrapper(data);
    }
}

